﻿//------------------------------------------------------------------------------
//  此代码版权声明为全文件覆盖，如有原作者特别声明，会在下方手动补充
//  此代码版权（除特别声明外的代码）归作者本人Diego所有
//  源代码使用协议遵循本仓库的开源协议及附加协议
//  Gitee源代码仓库：https://gitee.com/diego2098/ThingsGateway
//  Github源代码仓库：https://github.com/kimdiego2098/ThingsGateway
//  使用文档：https://kimdiego2098.github.io/
//  QQ群：605534569
//------------------------------------------------------------------------------

namespace ThingsGateway.NewLife.X;

/// <summary>数据位助手</summary>
public static class BitHelper
{
    /// <summary>获取数据位</summary>
    /// <param name="value">数值</param>
    /// <param name="position"></param>
    /// <returns></returns>
    public static Boolean GetBit(this UInt16 value, Int32 position)
    {
        return GetBits(value, position, 1) == 1;
    }

    /// <summary>获取数据位</summary>
    /// <param name="value">数值</param>
    /// <param name="position"></param>
    /// <returns></returns>
    public static Boolean GetBit(this Byte value, Int32 position)
    {
        if (position >= 8) return false;

        var mask = (2 << (1 - 1)) - 1;

        return ((Byte)((value >> position) & mask)) == 1;
    }

    /// <summary>获取数据位</summary>
    /// <param name="value">数值</param>
    /// <param name="position"></param>
    /// <param name="length"></param>
    /// <returns></returns>
    public static UInt16 GetBits(this UInt16 value, Int32 position, Int32 length)
    {
        if (length <= 0 || position >= 16) return 0;

        var mask = (2 << (length - 1)) - 1;

        return (UInt16)((value >> position) & mask);
    }

    /// <summary>设置数据位</summary>
    /// <param name="value">数值</param>
    /// <param name="position"></param>
    /// <param name="flag"></param>
    /// <returns></returns>
    public static UInt16 SetBit(this UInt16 value, Int32 position, Boolean flag)
    {
        return SetBits(value, position, 1, (flag ? (Byte)1 : (Byte)0));
    }

    /// <summary>设置数据位</summary>
    /// <param name="value">数值</param>
    /// <param name="position"></param>
    /// <param name="flag"></param>
    /// <returns></returns>
    public static Byte SetBit(this Byte value, Int32 position, Boolean flag)
    {
        if (position >= 8) return value;

        var mask = (2 << (1 - 1)) - 1;

        value &= (Byte)~(mask << position);
        value |= (Byte)(((flag ? 1 : 0) & mask) << position);

        return value;
    }

    /// <summary>设置数据位</summary>
    /// <param name="value">数值</param>
    /// <param name="position"></param>
    /// <param name="length"></param>
    /// <param name="bits"></param>
    /// <returns></returns>
    public static UInt16 SetBits(this UInt16 value, Int32 position, Int32 length, UInt16 bits)
    {
        if (length <= 0 || position >= 16) return value;

        var mask = (2 << (length - 1)) - 1;

        value &= (UInt16)~(mask << position);
        value |= (UInt16)((bits & mask) << position);

        return value;
    }
}
